package com.guslegend.service.impl;

import com.guslegend.constant.TimeConstant;
import com.guslegend.controller.request.ConfirmOrderRequest;
import com.guslegend.enums.BillTypeEnum;
import com.guslegend.enums.BizCodeEnum;
import com.guslegend.enums.ProductOrderPayTypeEnum;
import com.guslegend.enums.ProductOrderStateEnum;
import com.guslegend.exception.BizException;
import com.guslegend.interceptor.LoginInterceptor;
import com.guslegend.manager.ProductManager;
import com.guslegend.manager.ProductOrderManager;
import com.guslegend.model.LoginUser;
import com.guslegend.model.ProductDO;
import com.guslegend.model.ProductOrderDO;
import com.guslegend.service.ProductOrderService;
import com.guslegend.utils.CommonUtils;
import com.guslegend.utils.JsonData;
import com.guslegend.utils.JsonUtils;
import com.guslegend.vo.PayInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;

@Service
@Slf4j
public class ProductOrderServiceImpl implements ProductOrderService {

    @Autowired
    private ProductOrderManager productOrderManager;

    @Autowired
    private ProductManager productManager;

    @Override
    public Map<String, Object> page(int page, int size, String state) {

        Long accountNo = LoginInterceptor.threadLocal.get().getAccountNo();
        Map<String, Object> pageResult = productOrderManager.page(page, size, accountNo, state);
        return pageResult;
    }
    @Override
    public String queryProductOrderState(String outTradeNo) {

        Long accountNo = LoginInterceptor.threadLocal.get().getAccountNo();
        ProductOrderDO productOrderDO = productOrderManager.findByOutTradeNoAndAccountNo(outTradeNo, accountNo);
        if (productOrderDO==null){
            return "";
        }else {
            return productOrderDO.getState();
        }
    }

    /**
     *  防重提交（重点）(TODO)
     *  获取最新的流量包价格
     *  订单验价
     *     ■ 如果有优惠券或者其他抵扣
     *     ■ 验证前端显示和后台计算价格
     *  创建订单对象保存数据库
     *  发送延迟消息 - 用于自动关单（重点）(TODO)
     *  创建支付信息 - 对接三方支付（重点）(TODO)
     *  回调更新订单状态（重点）(TODO)
     *  支付成功创建流量包（重点）(TODO)
     * @param orderRequest
     * @return
     */
    @Override
    @Transactional
    public JsonData confirmOrder(ConfirmOrderRequest orderRequest) {

        LoginUser loginUser = LoginInterceptor.threadLocal.get();

        String orderOutTradeNo = CommonUtils.getStringNumRandom(32);

        ProductDO productDO = productManager.findDetailById(orderRequest.getProductId());

        //验证价格
        this.checkPrice(productDO,orderRequest);

        //创建订单
        ProductOrderDO productOrderDO = this.saveProductOrder(orderRequest,loginUser,orderOutTradeNo,productDO);



        //创建支付对象
        PayInfoVO payInfoVO = PayInfoVO.builder().accountNo(loginUser.getAccountNo())
                .outTradeNo(orderOutTradeNo).clientType(orderRequest.getClientType())
                .payType(orderRequest.getPayType()).title(productDO.getTitle()).description("")
                .payFee(orderRequest.getPayAmount()).orderPayTimeoutMills(TimeConstant.ORDER_PAY_TIMEOUT_MILLS)
                .build();

        //发送延迟消息  TODO


        //调用支付信息 TODO

        return null;
    }

    private ProductOrderDO saveProductOrder(ConfirmOrderRequest orderRequest, LoginUser loginUser, String orderOutTradeNo, ProductDO productDO) {
        ProductOrderDO productOrderDO = new ProductOrderDO();

        //设置用户信息
        productOrderDO.setAccountNo(loginUser.getAccountNo());
        productOrderDO.setNickname(loginUser.getUsername());


        //设置商品信息
        productOrderDO.setProductId(productDO.getId());
        productOrderDO.setProductTitle(productDO.getTitle());
        productOrderDO.setProductSnapshot(JsonUtils.obj2Json(productDO));
        productOrderDO.setProductAmount(productDO.getAmount());

        //设置订单信息
        productOrderDO.setBuyNum(orderRequest.getBuyNum());
        productOrderDO.setOutTradeNo(orderOutTradeNo);
        productOrderDO.setCreateTime(new Date());
        productOrderDO.setDel(0);

        //发票信息
        productOrderDO.setBillType(BillTypeEnum.valueOf(orderRequest.getBillType()).name());
        productOrderDO.setBillHeader(orderRequest.getBillHeader());
        productOrderDO.setBillReceiverPhone(orderRequest.getBillReceiverPhone());
        productOrderDO.setBillReceiverEmail(orderRequest.getBillReceiverEmail());
        productOrderDO.setBillContent(orderRequest.getBillContent());


        //实际支付总价
        productOrderDO.setPayAmount(orderRequest.getPayAmount());
        //总价，没使用优惠券
        productOrderDO.setTotalAmount(orderRequest.getTotalAmount());
        //订单状态
        productOrderDO.setState(ProductOrderStateEnum.NEW.name());
        //支付类型
        productOrderDO.setPayType(ProductOrderPayTypeEnum.valueOf(orderRequest.getPayType()).name());

        //插入数据库
        productOrderManager.add(productOrderDO);

        return productOrderDO;
    }

    private void checkPrice(ProductDO productDO, ConfirmOrderRequest orderRequest) {

        //后端计算价格
        BigDecimal bigTotal=BigDecimal.valueOf(orderRequest.getBuyNum()).multiply(productDO.getAmount());

        //前端传递总价和后端计算总价格是否一致, 如果有优惠券，也在这里进行计算
        if( bigTotal.compareTo(orderRequest.getPayAmount()) !=0 ){
            log.error("验证价格失败{}",orderRequest);
            throw new BizException(BizCodeEnum.ORDER_CONFIRM_PRICE_FAIL);
        }
    }


}
